/*	--- Lambda基础 --- 

在了解Lambda之前，我们先回顾一下Java的方法。

Java的方法分为【实例方法】，例如Integer定义的equals()方法：*/
public final class Integer {
	boolean equals(Object o) {
		//...
	}
}


// 以及【静态方法】，例如Integer定义的parseInt()方法：
public final class Integer {
	public static int parseInt(Sting s) {
		// ...
	}
}



// 无论是【实例方法】，还是【静态方法】，本质上都相当于【过程式语言的函数】。例如C函数：
char* strcpy(char* dest, char*src)


/*
只不过【Java的实例方法】隐含地传入了一个【this变量】，即【实例方法】总是有一个【隐含参数this】。

【函数式编程（Functional Programming）】是把【函数】作为【基本运算单元】，【函数】可以作为【变量】，可以【接收函数】，还可以【返回函数】。

历史上研究【函数式编程】的理论是【Lambda演算】，所以我们经常把支持【函数式编程的编码风格】称为【Lambda表达式】。


-----------------------------------------------------------


#	Lambda表达式


在Java程序中，我们经常遇到一大堆【单方法接口】，即【一个接口】只定义了【一个方法】：
	· Comparator
	· Runnable
	· Callable

以【Comparator】为例，我们想要调用【Arrays.sort()】时，可以传入一个【Comparator实例】，以【匿名类】方式编写如下：*/
String[] array = ...
Arrays.sort(array, new Comparator<String>() {
	public int compare(String s1, String s2) {
		return s1.compareTo(s2);
	}
});


/*
上述写法非常繁琐。

从Java 8开始，我们可以用【Lambda表达式】替换【单方法接口】。

改写上述代码如下： */
import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		String[] array = new String[] {"Apple", "Orange", "Banana", "Lemon"};
		Arrays.sort(array, (s1,s2) -> {
			return s1.compareTo(s2);
		});

		System.out.println(String.join(", ", array));
	}
}



// 观察【Lambda表达式】的写法，它只需要写出【方法定义】：
(s1, s2) -> {
	return s1.compareTo(s2);
}


/*
其中，参数是(s1, s2)，【参数类型】可以省略，因为编译器可以【自动推断出String类型】。

-> { ... }表示【方法体】，所有代码写在内部即可。

【Lambda表达式】没有【class定义】，因此【写法】非常简洁。

如果只有一行【return xxx】的代码，完全可以用【更简单的写法】：*/
Arrays.sort(array, (s1,s2) -> s1.compareTo(s2));

/*
返回值的类型也是由编译器自动推断的，这里推断出的返回值是int，因此，只要返回int，编译器就不会报错。


---------------------------------------------------


#	FunctionalInterface


我们把【只定义了单方法的接口】称之为【FunctionalInterface】，

用【注解@FunctionalInterface】标记。

例如，Callable接口：*/
@FunctionalInterface
public interface Callable<V> {
	V call() thrwos Exception;
}



// 再来看Comparator接口：
@FunctionalInterface
public inteface Comparator<T> {
	int compare(T o1, T o2);

	boolean equals(Object obj);

	default Comparator<T> reversed() {
		return Collections.reverseOrder(this);
	}

	default Comparator<T> thenComparing(Comparator<? super T> other) {
		//...
	}

	//...
}


/*
虽然【Comparator接口】有很多方法，但只有一个【抽象方法int compare(T o1, T o2)】，其他的方法都是【default方法】或【static方法】。

另外注意到boolean equals(Object obj)是Object定义的方法，不算在接口方法内。

因此，【Comparator】也是一个【FunctionalInterface】。



============================================================


#	----- lambda基础 の 小结 ----- 


1. 【单方法接口】被称为【FunctionalInterface】。

2. 接收【FunctionalInterface】作为【参数】的时候，可以把【实例化的匿名类】改写为【Lambda表达式】，能大大简化代码。

3. 【Lambda表达式】的【参数】和【返回值】均可由【编译器】自动推断。



*/










